#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest/doctest.h"

#include <cstdio>
#include "klib_http/url.hpp"
#include "klib/ansi_color.hpp"

using string_view = std::string_view;
using namespace klib::http;

void check_url(const char* url, bool expect, string_view proto, string_view user, string_view pass,
        string_view host, string_view port, string_view path, string_view query, string_view frag, string_view uri) {
    url_t u(url);
    if (!u.is_valid() && expect == u.is_valid())
        return;
    DOCTEST_INFO("URL = ", string_view(url));
    DOCTEST_CHECK_MESSAGE(u.protocol() == proto, "check protocol fail");
    DOCTEST_CHECK_MESSAGE(u.user() == user, "check user fail");
    DOCTEST_CHECK_MESSAGE(u.pass() == pass, "check pass fail");
    DOCTEST_CHECK_MESSAGE(u.host() == host, "check host fail");
    DOCTEST_CHECK_MESSAGE(u.port() == port, "check port fail");
    DOCTEST_CHECK_MESSAGE(u.path() == path, "check path fail");
    DOCTEST_CHECK_MESSAGE(u.query() == query, "check query fail");
    DOCTEST_CHECK_MESSAGE(u.fragment() == frag, "check fragment fail");
    DOCTEST_CHECK_MESSAGE(u.uri() == uri, "check uri fail");
}

TEST_CASE("url") {
    string_view nsv, h("http"), b("www.baidu.com");

    check_url("http://www.baidu.com", true, h, nsv, nsv, b, nsv, nsv, nsv, nsv, nsv);
    check_url("http://www.baidu.com:8080", true, h, nsv, nsv, b, "8080", nsv, nsv, nsv, nsv);
    check_url("http://www.baidu.com:8080/", true, h, nsv, nsv, b, "8080", "/", nsv, nsv, "/");
    check_url("http://www.baidu.com?n=4", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("http://www.baidu.com:8080?n=4", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("http://www.baidu.com/?n=4", true, h, nsv, nsv, b, nsv, "/", "n=4", nsv, "/?n=4");
    check_url("http://www.baidu.com#n=test", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("http://www.baidu.com/#n=text", true, h, nsv, nsv, b, nsv, "/", nsv, "n=text", "/#n=text");
    check_url("http://www.baidu.com/api/get", true, h, nsv, nsv, b, nsv, "/api/get", nsv, nsv, "/api/get");
    check_url("http://www.baidu.com/api/get?name=kiven", true, h, nsv, nsv, b, nsv, "/api/get", "name=kiven", nsv, "/api/get?name=kiven");
    check_url("http://www.baidu.com/api/get?name=kiven&age=3", true, h, nsv, nsv, b, nsv, "/api/get", "name=kiven&age=3", nsv, "/api/get?name=kiven&age=3");
    check_url("http://www.baidu.com/api/get?n=3#list", true, h, nsv, nsv, b, nsv, "/api/get", "n=3", "list", "/api/get?n=3#list");
    check_url("http://www.baidu.com?a=3#text", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("http://use:pas@www.baidu.com/#text", true, h, "use", "pas", b, nsv, "/", nsv, "text", "/#text");
    check_url("file:///path/1.png?t=3", true, "file", nsv, nsv, nsv, nsv, "/path/1.png", "t=3", nsv, "/path/1.png?t=3");
    check_url("file:///?t=3", true, "file", nsv, nsv, nsv, nsv, "/", "t=3", nsv, "/?t=3");
    check_url("file:///c:/windows/hosts.txt", true, "file", nsv, nsv, nsv, nsv, "/c:/windows/hosts.txt", nsv, nsv, "/c:/windows/hosts.txt");
    check_url("/file/read.txt", true, nsv, nsv, nsv, nsv, nsv, "/file/read.txt", nsv, nsv, "/file/read.txt");
    check_url("/file/read.txt?n=4", true, nsv, nsv, nsv, nsv, nsv, "/file/read.txt", "n=4", nsv, "/file/read.txt?n=4");
    check_url("/file/read.txt#n4", true, nsv, nsv, nsv, nsv, nsv, "/file/read.txt", nsv, "n4", "/file/read.txt#n4");
    check_url("abc/path", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("c:/abc/path", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("//abc/path", true, nsv, nsv, nsv, nsv, nsv, "//abc/path", nsv, nsv, "//abc/path");
    check_url("://abc/path", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("a://abc/path", true, "a", nsv, nsv, "abc", nsv, "/path", nsv, nsv, "/path");
    check_url("a:///", true, "a", nsv, nsv, nsv, nsv, "/", nsv, nsv, "/");
    check_url("a://", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("a://user:pass@/get", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
    check_url("a://user@/get", false, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv, nsv);
}